package com.yida.gwj.expend.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yida.common.core.exception.ServiceException;
import com.yida.common.core.utils.StringUtils;
import com.yida.common.security.utils.SecurityUtils;
import com.yida.gwj.common.domain.GwjBaseFile;
import com.yida.gwj.common.service.IGwjBaseFileService;
import com.yida.gwj.common.service.IGwjFileService;
import com.yida.gwj.common.utils.GwjEnumUtils;
import com.yida.gwj.expend.domain.GwjMaintenanceFundsBusinessAttachment;
import com.yida.gwj.expend.domain.dto.BaseFileInfoDTO;
import com.yida.gwj.expend.domain.dto.ConfirmReceiptDTO;
import com.yida.gwj.expend.domain.dto.GetAttachmentInfoRequest;
import com.yida.gwj.expend.domain.request.ApplicationReportRequest;
import com.yida.gwj.expend.domain.request.GwjSaveChangeSchemeRequest;
import com.yida.gwj.expend.domain.request.InsertAttachmentInfoRequest;
import com.yida.gwj.expend.enums.BusinessAttachmentServerTypeEnum;
import com.yida.gwj.expend.enums.BusinessAttachmentTypeEnum;
import com.yida.gwj.expend.enums.FlagStatusEnum;
import com.yida.gwj.expend.enums.MaintenanceFundsErrorEnum;
import com.yida.gwj.expend.mapper.GwjMaintenanceFundsBusinessAttachmentMapper;
import com.yida.gwj.expend.service.IGwjMaintenanceFundsBusinessAttachmentService;
import com.yida.system.api.domain.SysFile;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;

/**
 * 上传材料图片地址Service业务层处理
 *
 * @author lgp
 * @date 2023-03-21
 */
@Service
public class GwjMaintenanceFundsBusinessAttachmentServiceImpl implements IGwjMaintenanceFundsBusinessAttachmentService {

    private final Logger log = LoggerFactory.getLogger(GwjMaintenanceFundsBusinessAttachmentServiceImpl.class);

    @Autowired
    private IGwjBaseFileService baseFileService;
    @Autowired
    private GwjMaintenanceFundsBusinessAttachmentMapper gwjMaintenanceFundsBusinessAttachmentMapper;

    @Autowired
    private IGwjFileService iGwjFileService;

    /**
     * 查询上传材料图片地址
     *
     * @param attachmentId 上传材料图片地址主键
     * @return 上传材料图片地址
     */
    @Override
    public GwjMaintenanceFundsBusinessAttachment selectGwjMaintenanceFundsBusinessAttachmentByAttachmentId(Long attachmentId) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.selectGwjMaintenanceFundsBusinessAttachmentByAttachmentId(attachmentId);
    }

    /**
     * 查询上传材料图片地址列表
     *
     * @param gwjMaintenanceFundsBusinessAttachment 上传材料图片地址
     * @return 上传材料图片地址
     */
    @Override
    public List<GwjMaintenanceFundsBusinessAttachment> selectGwjMaintenanceFundsBusinessAttachmentList(GwjMaintenanceFundsBusinessAttachment gwjMaintenanceFundsBusinessAttachment) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.selectGwjMaintenanceFundsBusinessAttachmentList(gwjMaintenanceFundsBusinessAttachment);
    }

    /**
     * 新增上传材料图片地址
     *
     * @param gwjMaintenanceFundsBusinessAttachment 上传材料图片地址
     * @return 结果
     */
    @Override
    public int insertGwjMaintenanceFundsBusinessAttachment(GwjMaintenanceFundsBusinessAttachment gwjMaintenanceFundsBusinessAttachment) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.insertGwjMaintenanceFundsBusinessAttachment(gwjMaintenanceFundsBusinessAttachment);
    }

    /**
     * 修改上传材料图片地址
     *
     * @param gwjMaintenanceFundsBusinessAttachment 上传材料图片地址
     * @return 结果
     */
    @Override
    public int updateGwjMaintenanceFundsBusinessAttachment(GwjMaintenanceFundsBusinessAttachment gwjMaintenanceFundsBusinessAttachment) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.updateGwjMaintenanceFundsBusinessAttachment(gwjMaintenanceFundsBusinessAttachment);
    }

    /**
     * 批量删除上传材料图片地址
     *
     * @param attachmentIds 需要删除的上传材料图片地址主键
     * @return 结果
     */
    @Override
    public int deleteGwjMaintenanceFundsBusinessAttachmentByAttachmentIds(Long[] attachmentIds) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.deleteGwjMaintenanceFundsBusinessAttachmentByAttachmentIds(attachmentIds);
    }

    /**
     * 删除上传材料图片地址信息
     *
     * @param attachmentId 上传材料图片地址主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteGwjMaintenanceFundsBusinessAttachmentByAttachmentId(Long attachmentId) {
        GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = gwjMaintenanceFundsBusinessAttachmentMapper.selectGwjMaintenanceFundsBusinessAttachmentByAttachmentId(attachmentId);
        if (ObjectUtil.notEqual(SecurityUtils.getLoginUser().getUserid(), maintenanceFundsBusinessAttachment.getOperId())) {
            throw new ServiceException("只允许本人操作");
        }
        return gwjMaintenanceFundsBusinessAttachmentMapper.deleteGwjMaintenanceFundsBusinessAttachmentByAttachmentId(attachmentId);
    }

    @Override
    public List<GwjMaintenanceFundsBusinessAttachment> getGwjMaintenanceFundsBusinessAttachmentList(GetAttachmentInfoRequest getAttachmentInfoRequest) {
        GwjMaintenanceFundsBusinessAttachment gwjMaintenanceFundsBusinessAttachment = new GwjMaintenanceFundsBusinessAttachment();
        BeanUtil.copyProperties(getAttachmentInfoRequest, gwjMaintenanceFundsBusinessAttachment);
        List<GwjMaintenanceFundsBusinessAttachment> list = gwjMaintenanceFundsBusinessAttachmentMapper.selectGwjMaintenanceFundsBusinessAttachmentList(gwjMaintenanceFundsBusinessAttachment);
        if (StringUtils.isNotEmpty(list) && list.size() > 0) {
            list.stream().forEach(gfba -> {
                String content = gfba.getContent();
                if (StringUtils.isNotEmpty(content) && content.startsWith("{") && content.endsWith("}")) {
                    // 获取动态地址--暂时舍弃性能
                    JSONObject json = JSON.parseObject(content);
                    if (StringUtils.isEmpty(json.getString("fileName"))) {// 没有文件名不进行调用
                        return;
                    }
                    SysFile sysFile = iGwjFileService.getFileInfo(json.getString("fileName"), true);
                    json.put("fileUrl", sysFile.getUrl());
                    gfba.setContent(json.toString());
                    return;
                }
            });
        }
        return list;
        // return
        // gwjMaintenanceFundsBusinessAttachmentMapper.getGwjMaintenanceFundsBusinessAttachmentList(getAttachmentInfoRequest);
    }

    /**
     * 新增附件信息
     *
     * @param insertAttachmentInfoRequest
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long insertAttachmentInfo(InsertAttachmentInfoRequest insertAttachmentInfoRequest) {
        GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = new GwjMaintenanceFundsBusinessAttachment();
        maintenanceFundsBusinessAttachment.setReceiveFlag(FlagStatusEnum.FAL.getCode());
        maintenanceFundsBusinessAttachment.setType(insertAttachmentInfoRequest.getType());
        maintenanceFundsBusinessAttachment.setServerType(insertAttachmentInfoRequest.getServerType());
        maintenanceFundsBusinessAttachment.setServerIdentification(insertAttachmentInfoRequest.getServerIdentification());
        maintenanceFundsBusinessAttachment.setOperId(SecurityUtils.getLoginUser().getUserid());
        maintenanceFundsBusinessAttachment.setOperName(SecurityUtils.getLoginUser().getSysUser().getRealName());

        if (ObjectUtil.equal(insertAttachmentInfoRequest.getType(), BusinessAttachmentTypeEnum.REPORT.getCode())) {
            Optional.ofNullable(BusinessAttachmentServerTypeEnum.transfer(insertAttachmentInfoRequest.getServerType())).<ServiceException>orElseThrow(() -> {
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "附件信息类型异常");
            });
            try {
                switch (BusinessAttachmentServerTypeEnum.transfer(insertAttachmentInfoRequest.getServerType())) {
                    case APPLICATION_REPORT:
                        ApplicationReportRequest applicationReportRequest = JSONUtil.toBean(insertAttachmentInfoRequest.getContent(), ApplicationReportRequest.class);
                        applicationReportRequest.checkNull();
                        break;
                    case TRANSFORMATION_PLAN:
                        GwjSaveChangeSchemeRequest saveChangeSchemeRequest = JSONUtil.toBean(insertAttachmentInfoRequest.getContent(), GwjSaveChangeSchemeRequest.class);
                        saveChangeSchemeRequest.checkNull();
                        break;
                    default:
                        break;
                }
            } catch (Exception e) {
                log.error("插入附件信息异常 -> [{}]", e);
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + e.getMessage());
            }
            maintenanceFundsBusinessAttachment.setContent(insertAttachmentInfoRequest.getContent());
            maintenanceFundsBusinessAttachment.setAttachmentId(insertAttachmentInfoRequest.getAttachmentId());
        } else {
            GwjBaseFile baseFile = new GwjBaseFile();
            baseFile.setServerIdentification(IdUtil.getSnowflakeNextIdStr());
            baseFile.setFileName(insertAttachmentInfoRequest.getFileName());
            baseFile.setFileUrl(insertAttachmentInfoRequest.getFileUrl());
            if (ObjectUtil.isNull(baseFileService.insertGwjBaseFile(baseFile))) {
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "GwjBaseFile新增失败");
            }
            BaseFileInfoDTO baseFileInfoDTO = BeanUtil.copyProperties(baseFile, BaseFileInfoDTO.class);
            maintenanceFundsBusinessAttachment.setContent(JSONUtil.toJsonStr(baseFileInfoDTO));
            maintenanceFundsBusinessAttachment.setType(BusinessAttachmentTypeEnum.transfer(insertAttachmentInfoRequest.getFileType()).getCode());
        }
        int insertFlag = insertGwjMaintenanceFundsBusinessAttachment(maintenanceFundsBusinessAttachment);
        if (ObjectUtil.equal(insertFlag, FlagStatusEnum.FAL.getCode())) {
            throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "GwjMaintenanceFundsBusinessAttachment新增失败");
        }
        return maintenanceFundsBusinessAttachment.getAttachmentId();
    }

    @Override
    public int deleteGwjMaintenanceFundsBusinessAttachmentByServerIdentification(String serverIdentification) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.deleteGwjMaintenanceFundsBusinessAttachmentByServerIdentification(serverIdentification);
    }

    @Override
    public int insertBatchAttachment(List<GwjMaintenanceFundsBusinessAttachment> maintenanceFundsBusinessAttachmentList) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.insertBatchAttachment(maintenanceFundsBusinessAttachmentList);
    }

    /**
     * 修改上传材料图片地址
     *
     * @param confirmReceipt 上传材料图片地址
     * @return 结果
     */
    @Override
    public int updateBatchGwjMaintenanceFundsBusinessAttachment(ConfirmReceiptDTO confirmReceipt) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.updateBatchGwjMaintenanceFundsBusinessAttachment(confirmReceipt);
    }

    @Override
    public GwjMaintenanceFundsBusinessAttachment getGwjMaintenanceFundsBusinessAttachment(GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.getGwjMaintenanceFundsBusinessAttachment(maintenanceFundsBusinessAttachment);
    }

    @Override
    public List<BusinessAttachmentServerTypeEnum> checkNull(Supplier<Optional<List<GwjMaintenanceFundsBusinessAttachment>>> getAttachmentList, boolean receiveFlag, List<BusinessAttachmentServerTypeEnum> serverType) {
        Optional<List<GwjMaintenanceFundsBusinessAttachment>> attachmentListOpt = getAttachmentList.get();
        List<GwjMaintenanceFundsBusinessAttachment> maintenanceFundsBusinessAttachmentList = attachmentListOpt.orElse(ListUtil.toList());
        List<Integer> serverTypeList = maintenanceFundsBusinessAttachmentList.stream().map(GwjMaintenanceFundsBusinessAttachment::getServerType).collect(Collectors.toList());
        List<BusinessAttachmentServerTypeEnum> noServerTypeList = ListUtil.toList();
        for (BusinessAttachmentServerTypeEnum businessAttachmentServerTypeEnum : serverType) {
            if (!CollectionUtil.contains(serverTypeList, businessAttachmentServerTypeEnum.getCode())) {
                noServerTypeList.add(businessAttachmentServerTypeEnum);
            }
        }
        if (CollectionUtil.isNotEmpty(noServerTypeList)) {
            return noServerTypeList;
        }

        // 判断是否收件
        if (receiveFlag) {
            serverTypeList = maintenanceFundsBusinessAttachmentList.stream().filter(attachment -> ObjectUtil.equal(attachment.getReceiveFlag(), FlagStatusEnum.FAL.getCode())).map(GwjMaintenanceFundsBusinessAttachment::getServerType).collect(Collectors.toList());
            noServerTypeList = ListUtil.toList();
            for (BusinessAttachmentServerTypeEnum businessAttachmentServerTypeEnum : serverType) {
                if (CollectionUtil.contains(serverTypeList, businessAttachmentServerTypeEnum.getCode())) {
                    noServerTypeList.add(businessAttachmentServerTypeEnum);
                }
            }
            if (CollectionUtil.isNotEmpty(noServerTypeList)) {
                return noServerTypeList;
            }
        }
        return noServerTypeList;
    }

    @Override
    public int deleteGwjMaintenanceFundsBusinessAttachment(GetAttachmentInfoRequest getAttachmentInfoRequest) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.deleteGwjMaintenanceFundsBusinessAttachment(getAttachmentInfoRequest);
    }

    @Override
    public <T> T getContent2Entity(Class<T> t, Integer serverType, String serverIdentification, String... fieldName) {
        StringBuffer holdFieldName = new StringBuffer();
        AtomicInteger index = new AtomicInteger();
        Arrays.stream(fieldName).forEach((name) -> {
            holdFieldName.append("content ->> '$.").append(name).append("'").append(" AS ").append(name).append(",");
            // 最后一条不需要逗号
            if (ObjectUtil.equal(index.get(), fieldName.length - 1)) {
                holdFieldName.deleteCharAt(holdFieldName.length() - 1);
            }
            index.getAndIncrement();
        });
        Map<String, ?> map = gwjMaintenanceFundsBusinessAttachmentMapper.getContent2Entity(serverType, serverIdentification, holdFieldName.toString());
        return BeanUtil.toBean(map, t);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchInsertAttachmentInfo(List<InsertAttachmentInfoRequest> insertAttachmentInfoRequestList) {
        insertAttachmentInfoRequestList.forEach(insertAttachmentInfoRequest -> {
            GwjMaintenanceFundsBusinessAttachment maintenanceFundsBusinessAttachment = new GwjMaintenanceFundsBusinessAttachment();
            maintenanceFundsBusinessAttachment.setReceiveFlag(FlagStatusEnum.FAL.getCode());
            maintenanceFundsBusinessAttachment.setType(insertAttachmentInfoRequest.getType());
            maintenanceFundsBusinessAttachment.setServerType(insertAttachmentInfoRequest.getServerType());
            maintenanceFundsBusinessAttachment.setServerIdentification(insertAttachmentInfoRequest.getServerIdentification());
            maintenanceFundsBusinessAttachment.setAttachmentId(insertAttachmentInfoRequest.getAttachmentId());
            maintenanceFundsBusinessAttachment.setOperId(SecurityUtils.getLoginUser().getUserid());
            maintenanceFundsBusinessAttachment.setOperName(SecurityUtils.getLoginUser().getSysUser().getRealName());

            if (ObjectUtil.equal(insertAttachmentInfoRequest.getType(), BusinessAttachmentTypeEnum.REPORT.getCode())) {
                try {
                    Optional.ofNullable(BusinessAttachmentServerTypeEnum.transfer(insertAttachmentInfoRequest.getServerType())).<ServiceException>orElseThrow(() -> {
                        throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "附件信息类型异常");
                    });
                    switch (BusinessAttachmentServerTypeEnum.transfer(insertAttachmentInfoRequest.getServerType())) {
                        case APPLICATION_REPORT:
                            ApplicationReportRequest applicationReportRequest = JSONUtil.toBean(insertAttachmentInfoRequest.getContent(), ApplicationReportRequest.class);
                            applicationReportRequest.checkNull();
                            break;
                        case TRANSFORMATION_PLAN:
                            GwjSaveChangeSchemeRequest saveChangeSchemeRequest = JSONUtil.toBean(insertAttachmentInfoRequest.getContent(), GwjSaveChangeSchemeRequest.class);
                            saveChangeSchemeRequest.checkNull();
                            break;
                        default:
                            break;
                    }
                } catch (Exception e) {
                    log.error("插入附件信息异常 -> [{}]", e);
                    throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + e.getMessage());
                }
                maintenanceFundsBusinessAttachment.setContent(insertAttachmentInfoRequest.getContent());
            } else {
                GwjBaseFile baseFile = new GwjBaseFile();
                baseFile.setServerIdentification(IdUtil.getSnowflakeNextIdStr());
                baseFile.setFileName(insertAttachmentInfoRequest.getFileName());
                baseFile.setFileUrl(insertAttachmentInfoRequest.getFileUrl());
                if (ObjectUtil.isNull(baseFileService.insertGwjBaseFile(baseFile))) {
                    throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "GwjBaseFile新增失败");
                }
                BaseFileInfoDTO baseFileInfoDTO = BeanUtil.copyProperties(baseFile, BaseFileInfoDTO.class);
                maintenanceFundsBusinessAttachment.setContent(JSONUtil.toJsonStr(baseFileInfoDTO));
            }
            int insertFlag = insertGwjMaintenanceFundsBusinessAttachment(maintenanceFundsBusinessAttachment);
            if (ObjectUtil.equal(insertFlag, FlagStatusEnum.FAL.getCode())) {
                throw new ServiceException(GwjEnumUtils.getEnumConstantMsg(MaintenanceFundsErrorEnum.INSERT_ATTACHMENT_INFO) + "GwjMaintenanceFundsBusinessAttachment新增失败");
            }
        });
        return FlagStatusEnum.SUC.getCode();
    }

    // --------------------------新增功能区 hmh start-------------------
    /* 
     * 批量取消收件 
     * 
     * 20230718
     * 
     * hmh
     */
    @Override
    public int batchCancelReceipt(Long[] attachmentId) {
        return gwjMaintenanceFundsBusinessAttachmentMapper.batchCancelReceipt(attachmentId);
    }
    // --------------------------新增功能区 hmh end-------------------

}
